package edu.vt.ece_3574.amber_alert.database;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.android.maps.GeoPoint;

import edu.vt.ece_3574.amber_alert.accounts.Account;
import edu.vt.ece_3574.amber_alert.accounts.Friend;

import android.os.AsyncTask;
import android.util.Log;

public class GetAccountFromServerByNameHandler extends AsyncTask<Void, Void, Account> {
	private String name;

	public GetAccountFromServerByNameHandler(String name) {
		super();
		this.name = name;
	}

    protected Account doInBackground(Void... params) { 
    	Account accountToReturn;
    	
    	String serialNumber = null;
    	String name = null;
    	String number = null;
    	String password = null;
    	String type = null;
    	String locationString = null;
    	String associatedAccountsString = null;
    	String associatedFriendsString = null;
    	
    	String result = "";
		InputStream is = null;
		
		//the serial number data to send
		ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		nameValuePairs.add(new BasicNameValuePair("name", this.name));

		//http post
		try {
			HttpClient httpclient = new DefaultHttpClient();
			HttpPost httppost = new HttpPost(DatabaseHandler.databaseURL + "getAccountByName.php");
			httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
			HttpResponse response = httpclient.execute(httppost); 
			HttpEntity entity = response.getEntity();
			is = entity.getContent();
		}
		catch(Exception e) {
			Log.e("log_tag", "Error in http connection "+e.toString());
		}

		//convert response to string
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
			StringBuilder sb = new StringBuilder();
			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
			is.close();
			result=sb.toString();
		}
		catch (Exception e) {
			Log.e("log_tag", "Error converting result "+e.toString());
		}
		//parse json data
		try{
			JSONArray jArray = new JSONArray(result);
			for(int i=0;i<jArray.length();i++) {
				JSONObject json_data = jArray.getJSONObject(i);
				
				serialNumber = json_data.getString("SerialNumber");
				name = json_data.getString("Name");
				password = json_data.getString("Password");
				number = json_data.getString("PhoneNumber");
				type = json_data.getString("Type");
				locationString = json_data.getString("Location");
				associatedAccountsString = json_data.getString("AssociatedAccounts");
				associatedFriendsString = json_data.getString("Friends");
			}
		}
		catch (JSONException e) {
			Log.e("log_tag", "Error parsing data "+e.toString());
		}
		
		accountToReturn = new Account(number, name, type, password);
		
		if (locationString.contains(":")) {
			accountToReturn.setLocation(getGeoPoint(locationString));
		}
		accountToReturn.setSerialNumber(serialNumber);
		
		if (!associatedAccountsString.equals("")) {
			accountToReturn.setAssociatedAccounts(getAccountAssociations(associatedAccountsString));
		}
		
		if (!associatedFriendsString.equals("")) {
			accountToReturn.setAssociatedFriends(getAccountFriends(associatedFriendsString));
		}
		
		return accountToReturn;
    } 
    
    private GeoPoint getGeoPoint(String locationString) {
    	String[] locationParts = locationString.split(":");
    	String longitude = locationParts[0];
    	String latitude = locationParts[1];

    	//Create a new point with the latitude and longitude, correctly formatted
    	int latitudeInt = new BigDecimal(latitude).intValue();
    	int longitudeInt = new BigDecimal(longitude).intValue();
    	return new GeoPoint(longitudeInt, latitudeInt);
    }
    
    private ArrayList<String> getAccountAssociations(String associatedAccountsString) {
    	ArrayList<String> associations = new ArrayList<String>();
    	
    	String[] eachAccountSplit = associatedAccountsString.split(";");
    	for (String accountName : eachAccountSplit) {
    		if (!accountName.equals("")) {
    			associations.add(accountName);
    		}
    	}
    	return associations;
    }
    
    private ArrayList<Friend> getAccountFriends(String associatedFriendsString) {
    	ArrayList<Friend> friends = new ArrayList<Friend>();
    	
    	String[] eachFriendSplit = associatedFriendsString.split(";");
    	for (String friend : eachFriendSplit) {
    		String[] friendSplit = friend.split(":");
    		if (!friend.equals("")) {
    			Friend newFriend = new Friend(friendSplit[0], friendSplit[1], friendSplit[2]);
    			friends.add(newFriend);
    		}
    	}
    	return friends;
    }
}
